`include "common_header.verilog"

//  *************************************************************************
//  File : tx_block_check_10l.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized Reproduction or Use is Expressly Prohibited. 
//  Copyright (c) 2001 Morethanip
//  MorethanIP GmbH, Domagkstr33/75, 80807 Muenchen, GERMANY
//  info@morethanip.com
//  *************************************************************************
//  Version: $Id: tx_block_check_10l.v,v 1.1.1.1 2014/07/15 08:12:14 dk Exp $
//  Author : Serge S.
//  Initial: 01/02/2002
//  *************************************************************************
// 
//  Description: 10G Base-R PCS Transmit Encoder: ENCODE State Machine 
// 
//  *************************************************************************

module tx_block_check_10l (
   reset,
   sw_reset,
   clk,
   clk_ena,
   `ifdef MTIPPCS_EEE_ENA
   t_type_li,   
   `endif
   t_type_c,
   t_type_s,
   t_type_t,
   t_type_d,
   t_type_e,
   t_type_val,
   encode,
   local_fault,
   error);

input   reset;          //  asynch reset
input   sw_reset;       //  Synchronous Software Reset
input   clk;         //  system clock    
input   clk_ena;         //  clock enable
`ifdef MTIPPCS_EEE_ENA
input   t_type_li;              //   LI Block type received   
`endif
input   t_type_c;       //   C Block type received
input   t_type_s;       //   S Block type received
input   t_type_t;       //   T Block type received
input   t_type_d;       //   D Block type received
input   t_type_e;       //   E Block type received
input   t_type_val;     //  Block type received valide     
output  encode;         //  encode can be done 
output  local_fault;    //  local fault should be sent 
output  error; 

reg     encode; 
wire    local_fault; 
//  error should be sent 
// 
wire    error; 


// =============================================================
`ifdef MTIPPCS_EEE_ENA
wire    t_type_li_s;    //  LI Block type received 
`endif
wire    t_type_c_s;     //   C Block type received
wire    t_type_s_s;     //   S Block type received
wire    t_type_t_s;     //   T Block type received
wire    t_type_d_s;     //   D Block type received
wire    t_type_e_s;     //   E Block type received
wire    t_type_val_s;   //  Block type received valide     

// 
// ---------------------------------------
//  State machine
// ---------------------------------------
reg     tx_init;        //   init state send local fault
`ifdef MTIPPCS_EEE_ENA
reg     tx_li;          //  LI Block type detected 
`endif
reg     tx_c;           //   C Block type detected
reg     tx_t;           //   T Block type detected
reg     tx_d;           //   D Block type detected
reg     tx_e;           //   E Block type detected


// 
// =======================================================================

assign t_type_c_s = t_type_c; //   C Block type received
assign t_type_s_s = t_type_s; //   S Block type received
assign t_type_t_s = t_type_t; //   T Block type received
assign t_type_d_s = t_type_d; //   D Block type received
assign t_type_e_s = t_type_e; //   E Block type received
assign t_type_val_s = t_type_val; //  Block type received valide 
`ifdef MTIPPCS_EEE_ENA
assign t_type_li_s = t_type_li;      //  LI Block type received
`endif
// 
// =====================================================================
//  State machine
// =====================================================================
always @(posedge clk or posedge reset)
   begin : p_state
   if (reset == 1'b 1)
      begin
      tx_init <= 1'b 1;	//   init state            - send local fault
      tx_c <= 1'b 0;	//   C Block type detected - encode
      tx_t <= 1'b 0;	//   T Block type detected - encode
      tx_d <= 1'b 0;	//   D Block type detected - encode
      tx_e <= 1'b 0;	//   E Block type detected - send error
      `ifdef MTIPPCS_EEE_ENA
      tx_li <= 1'b 0;   //   LI Block type detected - encode
      `endif
      end
   else if (sw_reset==1'b 1)
      begin
      tx_init <= 1'b 1;	//   init state            - send local fault
      tx_c <= 1'b 0;	//   C Block type detected - encode
      tx_t <= 1'b 0;	//   T Block type detected - encode
      tx_d <= 1'b 0;	//   D Block type detected - encode
      tx_e <= 1'b 0;	//   E Block type detected - send error
     `ifdef MTIPPCS_EEE_ENA
      tx_li <= 1'b 0;
     `endif
      end

    else if (clk_ena == 1'b 1)
      begin
// --------------------------------------
//   init state    - send local fault
// --------------------------------------
      tx_init <= 1'b 0;	
// --------------------------------------
// --------------------------------------------
//   C Block type detected - encode
// --------------------------------------------       
      if (      tx_init == 1'b 1 & t_type_c_s == 1'b 1 | 
	        tx_c == 1'b 1 & (t_type_c_s == 1'b 1 | t_type_val_s == 1'b 0) | 
	        tx_t == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 | 
	        tx_e == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1
`ifdef MTIPPCS_EEE_ENA	        
	      | tx_li == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1
`endif	        
	        )
         begin
                tx_c <= 1'b 1;	
         end
      else
         begin
                tx_c <= 1'b 0;	
         end
         
// -------------------------------------------
//   D Block type detected - encode
// ------------------------------------------- 
      if (      tx_init == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_c == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_t == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 0)
         begin
                tx_d <= 1'b 1;	
         end
      else
         begin
                tx_d <= 1'b 0;	
         end
// --------------------------------------------       
//   T Block type detected - encode
// --------------------------------------------       
      if (      tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
                tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
	        tx_t == 1'b 1 & t_type_val_s == 1'b 0)
            begin
            tx_t <= 1'b 1;	
            end
         else
            begin
            tx_t <= 1'b 0;	
            end


`ifdef MTIPPCS_EEE_ENA	        
// --------------------------------------------
//  LI Block type detected - encode
// -------------------------------------        
      if (tx_c  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
          tx_t  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
          tx_e  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
          tx_li == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
          tx_li == 1'b 1 & t_type_val_s == 1'b 0)
         begin
         tx_li <= 1'b 1;   
         end
      else
         begin
         tx_li <= 1'b 0;   
         end
`endif


// ---------------------------------------------       
//   E Block type detected - send error
// --------------------------------------------       


`ifdef MTIPPCS_EEE_ENA	

      if (      tx_init == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1 | t_type_li_s == 1'b 1) | 
                tx_c    == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1) | 
                tx_d    == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_c_s == 1'b 1 | t_type_s_s == 1'b 1 | t_type_li_s == 1'b 1) | 
                tx_t    == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1) | 
                tx_li   == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_s_s == 1'b 1 | t_type_t_s == 1'b 1) | 
                tx_e    == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_s_s == 1'b 1) |
                tx_e    == 1'b 1 & t_type_val_s == 1'b 0)

`else
         if (   tx_init == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1) |          
	        tx_c == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1) | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_c_s == 1'b 1 | t_type_s_s == 1'b 1) | 
	        tx_t == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_d_s == 1'b 1 | t_type_t_s == 1'b 1) | 
	        tx_e == 1'b 1 & t_type_val_s == 1'b 0 | 
	        tx_e == 1'b 1 & t_type_val_s == 1'b 1 & (t_type_e_s == 1'b 1 | t_type_s_s == 1'b 1))
`endif
            begin
            tx_e <= 1'b 1;	
            end
         else
            begin
            tx_e <= 1'b 0;	
            end


// --------------------------------------------       
      end
   end
// 

// ----------------------
//  encode can be done
// ---------------------- 

always @(tx_init or t_type_c_s or t_type_val_s or t_type_s_s or t_type_d_s or t_type_t_s or
         tx_c or tx_d or tx_e or tx_t
`ifdef MTIPPCS_EEE_ENA
         or t_type_li_s or tx_li
`endif
)
   begin : p_encode
   
`ifdef MTIPPCS_EEE_ENA
   if (
      // C Block type detected
      tx_init == 1'b 1 & t_type_c_s == 1'b 1 | 
      tx_c == 1'b 1 & (t_type_c_s == 1'b 1 | t_type_val_s == 1'b 0) | 
      tx_t == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 | 
      tx_e == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 | 
      tx_li == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 |

      // D Block type detected
      tx_init == 1'b 1 & t_type_s_s == 1'b 1 | 
      tx_c == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
      tx_t == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
      tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
      tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
      tx_d == 1'b 1 & t_type_val_s == 1'b 0 | 

      // T Block type detected
      tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
      tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
      tx_t == 1'b 1 & t_type_val_s == 1'b 0 |

      // LI Block type detected
      tx_c  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
      tx_t  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
      tx_e  == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
      tx_li == 1'b 1 & t_type_val_s == 1'b 1 & t_type_li_s == 1'b1 |
      tx_li == 1'b 1 & t_type_val_s == 1'b 0)
      
`else
   if (         tx_init == 1'b 1 & t_type_c_s == 1'b 1 | 
	        tx_c == 1'b 1 & (t_type_c_s == 1'b 1 | t_type_val_s == 1'b 0) | 
	        tx_t == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 | 
	        tx_e == 1'b 1 & t_type_c_s == 1'b 1 & t_type_val_s == 1'b 1 | 
	        tx_init == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_c == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_t == 1'b 1 & t_type_val_s == 1'b 1 & t_type_s_s == 1'b 1 | 
	        tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_d_s == 1'b 1 | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 0 | 
	        tx_d == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
	        tx_e == 1'b 1 & t_type_val_s == 1'b 1 & t_type_t_s == 1'b 1 | 
	        tx_t == 1'b 1 & t_type_val_s == 1'b 0)
`endif
      begin
        encode = 1'b 1;	
      end
   else
      begin
        encode = 1'b 0;	
      end

   end

// ---------------------------------------
//  local fault should be sent 
// ---------------------------------------
                    
assign local_fault = tx_init; 

// ---------------------------------------
//  error should be sent
// ---------------------------------------

assign error = tx_e; 


endmodule // module tx_block_check_10l
